"""
学生选课管理路由
"""
from flask import request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from app.blueprints.api import api_bp
from app.models.user import User
from app.models.course import Course
from app.models.student_course import StudentCourse
from app.models.log import SystemLog
from app.extensions import db
from datetime import datetime
from decimal import Decimal


@api_bp.route('/student/available-courses', methods=['GET'])
@jwt_required()
def get_available_courses():
    """获取学生可选课程列表（含人数统计）"""
    try:
        current_user_id = int(get_jwt_identity())
        user = User.query.get(current_user_id)
        
        if user.role != 'student':
            return jsonify({
                'success': False,
                'error': 'Permission denied'
            }), 403
        
        # 获取查询参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        department = request.args.get('department')
        semester = request.args.get('semester')
        search = request.args.get('search', '').strip()
        
        # 获取学生已选课程ID（排除已退课）
        enrolled_course_ids = db.session.query(StudentCourse.course_id).filter(
            StudentCourse.student_id == current_user_id,
            StudentCourse.status.in_(['enrolled', 'completed'])
        ).all()
        enrolled_ids = [c[0] for c in enrolled_course_ids]
        
        # 构建查询
        query = Course.query
        
        if department:
            query = query.filter_by(department=department)
        if semester:
            query = query.filter_by(semester=semester)
        if search:
            query = query.filter(
                db.or_(
                    Course.name.like(f'%{search}%'),
                    Course.code.like(f'%{search}%'),
                    Course.description.like(f'%{search}%')
                )
            )
        
        # 分页
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        courses = []
        for course in pagination.items:
            course_data = course.to_dict()
            
            # 统计当前选课人数（排除已退课）
            enrollment_count = StudentCourse.query.filter(
                StudentCourse.course_id == course.id,
                StudentCourse.status.in_(['enrolled', 'completed'])
            ).count()
            course_data['enrollment_count'] = enrollment_count
            
            # 是否已满
            if course.max_students:
                course_data['is_full'] = enrollment_count >= course.max_students
            else:
                course_data['is_full'] = False
            
            # 是否已选
            course_data['is_enrolled'] = course.id in enrolled_ids
            
            # 教师信息
            if course.instructor:
                course_data['instructor_name'] = f"{course.instructor.last_name}{course.instructor.first_name}"
            else:
                course_data['instructor_name'] = '未分配'
            
            courses.append(course_data)
        
        return jsonify({
            'success': True,
            'data': courses,
            'pagination': {
                'page': page,
                'per_page': per_page,
                'total': pagination.total,
                'pages': pagination.pages
            }
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@api_bp.route('/student/my-courses', methods=['GET'])
@jwt_required()
def get_student_my_courses():
    """获取学生已选课程列表"""
    try:
        current_user_id = int(get_jwt_identity())
        user = User.query.get(current_user_id)
        
        if user.role != 'student':
            return jsonify({
                'success': False,
                'error': 'Permission denied'
            }), 403
        
        # 获取学生选课记录
        student_courses = StudentCourse.query.filter_by(
            student_id=current_user_id
        ).all()
        
        courses = []
        for sc in student_courses:
            if not sc.course:
                continue
            
            course_data = sc.course.to_dict()
            course_data['enrollment_status'] = sc.status
            course_data['enrollment_date'] = sc.enrollment_date.isoformat() if sc.enrollment_date else None
            
            # 成绩信息（添加明细）
            course_data['score'] = float(sc.score) if sc.score else None
            course_data['letter_grade'] = sc.letter_grade
            course_data['midterm_score'] = float(sc.midterm_score) if sc.midterm_score else None  # 平时成绩
            course_data['final_score'] = float(sc.final_score) if sc.final_score else None  # 考试成绩
            
            # 出勤信息（添加详情）
            course_data['attendance_rate'] = float(sc.attendance_rate) if sc.attendance_rate else None
            course_data['total_classes'] = sc.total_classes if sc.total_classes else None  # 总课时
            course_data['attended'] = sc.attended if sc.attended else None  # 实际出勤
            
            # 教师信息
            if sc.course.instructor:
                course_data['instructor_name'] = f"{sc.course.instructor.last_name}{sc.course.instructor.first_name}"
            else:
                course_data['instructor_name'] = '未分配'
            
            # 当前选课人数（排除已退课）
            enrollment_count = StudentCourse.query.filter(
                StudentCourse.course_id == sc.course_id,
                StudentCourse.status.in_(['enrolled', 'completed'])
            ).count()
            course_data['enrollment_count'] = enrollment_count
            
            courses.append(course_data)
        
        return jsonify({
            'success': True,
            'data': courses,
            'total': len(courses)
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@api_bp.route('/student/enroll/<int:course_id>', methods=['POST'])
@jwt_required()
def enroll_course(course_id):
    """学生选课"""
    try:
        current_user_id = int(get_jwt_identity())
        user = User.query.get(current_user_id)
        
        if user.role != 'student':
            return jsonify({
                'success': False,
                'error': 'Permission denied'
            }), 403
        
        # 获取学生profile
        if not user.student_profile:
            return jsonify({
                'success': False,
                'error': 'Student profile not found'
            }), 404
        
        student_profile_id = user.student_profile.id
        
        # 验证课程存在
        course = Course.query.get(course_id)
        if not course:
            return jsonify({
                'success': False,
                'error': 'Course not found'
            }), 404
        
        # 检查是否已选（排除已退课）
        existing = StudentCourse.query.filter(
            StudentCourse.student_id == student_profile_id,
            StudentCourse.course_id == course_id,
            StudentCourse.status.in_(['enrolled', 'completed'])
        ).first()
        
        if existing:
            return jsonify({
                'success': False,
                'error': 'Already enrolled in this course'
            }), 400
        
        # 检查是否有已退课记录，如果有则重新激活
        dropped = StudentCourse.query.filter_by(
            student_id=student_profile_id,
            course_id=course_id,
            status='dropped'
        ).first()
        
        if dropped:
            # 重新激活选课记录
            dropped.status = 'enrolled'
            dropped.enrollment_date = datetime.utcnow().date()
            dropped.updated_at = datetime.utcnow()
            
            # 记录日志
            log = SystemLog(
                user_id=current_user_id,
                action='re-enroll',
                resource_type='course',
                resource_id=str(course_id),
                ip_address=request.remote_addr,
                status='success',
                level='INFO',
                message=f'Student re-enrolled in course {course.code}'
            )
            db.session.add(log)
            db.session.commit()
            
            return jsonify({
                'success': True,
                'message': 'Successfully re-enrolled in course',
                'data': {
                    'course_id': course_id,
                    'course_name': course.name,
                    'enrollment_date': dropped.enrollment_date.isoformat()
                }
            }), 201
        
        # 检查课程是否已满（排除已退课）
        if course.max_students:
            enrollment_count = StudentCourse.query.filter(
                StudentCourse.course_id == course_id,
                StudentCourse.status.in_(['enrolled', 'completed'])
            ).count()
            if enrollment_count >= course.max_students:
                return jsonify({
                    'success': False,
                    'error': f'Course is full (max: {course.max_students})'
                }), 400
        
        # 创建选课记录
        student_course = StudentCourse(
            student_id=student_profile_id,
            course_id=course_id,
            enrollment_date=datetime.utcnow().date(),
            status='enrolled',
            total_classes=48,  # 默认总课时
            attended=0,
            attendance_rate=Decimal('0.00')
        )
        
        db.session.add(student_course)
        
        # 记录日志
        log = SystemLog(
            user_id=current_user_id,
            action='enroll',
            resource_type='course',
            resource_id=str(course_id),
            ip_address=request.remote_addr,
            status='success',
            level='INFO',
            message=f'Student enrolled in course {course.code}'
        )
        db.session.add(log)
        
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': 'Successfully enrolled in course',
            'data': {
                'course_id': course_id,
                'course_name': course.name,
                'enrollment_date': student_course.enrollment_date.isoformat()
            }
        }), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@api_bp.route('/student/drop/<int:course_id>', methods=['DELETE'])
@jwt_required()
def drop_course(course_id):
    """学生退课"""
    try:
        current_user_id = int(get_jwt_identity())
        user = User.query.get(current_user_id)
        
        if user.role != 'student':
            return jsonify({
                'success': False,
                'error': 'Permission denied'
            }), 403
        
        # 查找选课记录
        student_course = StudentCourse.query.filter_by(
            student_id=current_user_id,
            course_id=course_id
        ).first()
        
        if not student_course:
            return jsonify({
                'success': False,
                'error': 'Not enrolled in this course'
            }), 404
        
        # 检查是否允许退课（例如：已完成的课程不允许退课）
        if student_course.status == 'completed':
            return jsonify({
                'success': False,
                'error': 'Cannot drop completed course'
            }), 400
        
        course_name = student_course.course.name if student_course.course else 'Unknown'
        
        # 删除选课记录（或改为修改状态为 'dropped'）
        # 这里选择修改状态，保留历史记录
        student_course.status = 'dropped'
        student_course.updated_at = datetime.utcnow()
        
        # 记录日志
        log = SystemLog(
            user_id=current_user_id,
            action='drop',
            resource_type='course',
            resource_id=str(course_id),
            ip_address=request.remote_addr,
            status='success',
            level='INFO',
            message=f'Student dropped course {course_name}'
        )
        db.session.add(log)
        
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': 'Successfully dropped course',
            'data': {
                'course_id': course_id,
                'course_name': course_name
            }
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@api_bp.route('/student/learning-alerts', methods=['GET'])
@jwt_required()
def get_student_learning_alerts():
    """获取学生的学习预警信息"""
    try:
        current_user_id = int(get_jwt_identity())
        user = User.query.get(current_user_id)
        
        if user.role != 'student':
            return jsonify({
                'success': False,
                'error': 'Permission denied'
            }), 403
        
        # 获取学生选课记录（在读课程）
        student_courses = StudentCourse.query.filter_by(
            student_id=current_user_id,
            status='enrolled'
        ).all()
        
        alerts = {
            'failing_courses': [],  # 成绩不及格
            'low_attendance': [],   # 出勤率低
            'at_risk': [],          # 综合风险
            'total_warnings': 0
        }
        
        for sc in student_courses:
            if not sc.course:
                continue
            
            course_name = sc.course.name
            course_id = sc.course_id
            
            # 检查成绩不及格（<60分）
            if sc.score is not None and sc.score < 60:
                alerts['failing_courses'].append({
                    'course_id': course_id,
                    'course_name': course_name,
                    'score': float(sc.score),
                    'letter_grade': sc.letter_grade,
                    'alert_type': 'failing',
                    'message': f'成绩 {sc.score:.2f}分，未达到及格线'
                })
            
            # 检查出勤率低（<70%）
            if sc.attendance_rate is not None and sc.attendance_rate < 70:
                alerts['low_attendance'].append({
                    'course_id': course_id,
                    'course_name': course_name,
                    'attendance_rate': float(sc.attendance_rate),
                    'total_classes': sc.total_classes,
                    'attended': sc.attended,
                    'alert_type': 'attendance',
                    'message': f'出勤率 {sc.attendance_rate:.1f}%，低于要求'
                })
            
            # 综合风险：成绩偏低（60-70分）且出勤率一般（70-80%）
            if (sc.score is not None and 60 <= sc.score < 70 and
                sc.attendance_rate is not None and 70 <= sc.attendance_rate < 80):
                alerts['at_risk'].append({
                    'course_id': course_id,
                    'course_name': course_name,
                    'score': float(sc.score),
                    'attendance_rate': float(sc.attendance_rate),
                    'alert_type': 'at_risk',
                    'message': f'成绩和出勤率均偏低，需要改进'
                })
        
        # 计算总预警数
        alerts['total_warnings'] = (
            len(alerts['failing_courses']) +
            len(alerts['low_attendance']) +
            len(alerts['at_risk'])
        )
        
        # 生成学习建议
        suggestions = []
        if alerts['failing_courses']:
            suggestions.append('建议加强学习，重点关注不及格课程')
        if alerts['low_attendance']:
            suggestions.append('建议提高出勤率，避免影响成绩')
        if alerts['at_risk']:
            suggestions.append('建议合理安排学习时间，保持良好的学习状态')
        
        alerts['suggestions'] = suggestions
        
        return jsonify({
            'success': True,
            'data': alerts
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@api_bp.route('/student/course/<int:course_id>/rank', methods=['GET'])
@jwt_required()
def get_student_course_rank(course_id):
    """获取学生在某门课程中的排名"""
    try:
        current_user_id = int(get_jwt_identity())
        user = User.query.get(current_user_id)
        
        if user.role != 'student':
            return jsonify({
                'success': False,
                'error': 'Permission denied'
            }), 403
        
        # 验证课程存在
        course = Course.query.get(course_id)
        if not course:
            return jsonify({
                'success': False,
                'error': 'Course not found'
            }), 404
        
        # 获取学生在该课程的成绩
        student_course = StudentCourse.query.filter_by(
            student_id=current_user_id,
            course_id=course_id
        ).first()
        
        if not student_course or student_course.score is None:
            return jsonify({
                'success': False,
                'error': 'No score available for this course'
            }), 404
        
        # 查询该课程所有有成绩的学生（排除已退课）
        all_scores = StudentCourse.query.filter(
            StudentCourse.course_id == course_id,
            StudentCourse.status.in_(['enrolled', 'completed']),
            StudentCourse.score.isnot(None)
        ).order_by(StudentCourse.score.desc()).all()
        
        # 计算排名和统计信息
        total_students = len(all_scores)
        student_rank = None
        scores_list = []
        
        for idx, sc in enumerate(all_scores, 1):
            scores_list.append(float(sc.score))
            if sc.student_id == current_user_id:
                student_rank = idx
        
        if student_rank is None:
            return jsonify({
                'success': False,
                'error': 'Ranking not available'
            }), 404
        
        # 计算百分位（排名越高百分位越高）
        percentile = (1 - (student_rank - 1) / total_students) * 100 if total_students > 0 else 0
        
        # 计算课程平均分
        avg_score = sum(scores_list) / len(scores_list) if scores_list else 0
        
        # 计算与平均分的差距
        score_diff = float(student_course.score) - avg_score
        
        return jsonify({
            'success': True,
            'data': {
                'course_id': course_id,
                'course_name': course.name,
                'student_score': float(student_course.score),
                'rank': student_rank,
                'total_students': total_students,
                'percentile': round(percentile, 1),
                'average_score': round(avg_score, 2),
                'score_diff': round(score_diff, 2),
                'rank_description': (
                    '优秀' if percentile >= 80 else
                    '良好' if percentile >= 60 else
                    '中等' if percentile >= 40 else
                    '偏低' if percentile >= 20 else
                    '需要努力'
                )
            }
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

